package com.shengdong.water.base

import android.net.http.NetworkException
import android.util.Log
import android.view.WindowManager.BadTokenException
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.shengdong.water.code.bean.PageData
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.receiveAsFlow

/**
 * ViewModel 基类
 */
open class BaseViewModel : ViewModel() {

    // UI 状态
    private val _uiState = MutableStateFlow<UiState>(UiState.Idle)
    val uiState : SharedFlow<UiState> = _uiState


    private val _refreshLoadStatus = MutableSharedFlow<RefreshLoadStatus>(replay = 1)
    val refreshLoadStatus = _refreshLoadStatus.asSharedFlow()


    /**
     * 发送 UI 状态
     */
    protected fun sendUiState(state: UiState) {
        viewModelScope.launch {
            _uiState.emit(state)
        }
    }


    /**
     * 处理网络请求
     */
    protected fun <T> requestFlow(
        request: suspend () -> BaseResponse<T>
    ): Flow<ResultState<T>> = flow {
        val response = request()
        if (response.isSuccess()) {
            response.data?.let {
                emit(ResultState.Success(it))
            } ?: emit(ResultState.Error(-1, "数据为空"))
        } else {
            emit(ResultState.Error(response.code, response.msg))
        }
    }.onStart {
        emit(ResultState.Loading)
    }.catch { e ->
        emit(ResultState.Error(-1, e.message ?: "未知错误"))
    }


    
    // 显示加载状态
    protected  fun showLoading(loading: String) {
        sendUiState(UiState.ShowLoading(loading))
    }
    
    // 隐藏加载状态
    protected  fun dismissLoading() {
        sendUiState(UiState.DismissLoading)
    }

    // 发送错误信息
    protected  fun showError(error: String) {
        sendUiState(UiState.Error(error))
    }


    // 处理网络请求的通用方法
    protected fun <T> handleRequest(
        showLoading: Boolean = true,
        loading: String = "加载中...",
        flow: Flow<ResultState<T>>,
        onSuccess:  (T) -> Unit,
        onToast:  (String) -> Unit,
        onError: ((Int, String) -> Unit)? = null,
        onException: ((Throwable) -> Unit)? = null,
    ) {
            viewModelScope.launch {
                flow.onStart {
                    if (showLoading) showLoading(loading)
                }.catch { e ->
                    dismissLoading()
                    onException?.invoke(e) ?:
                    emit(ResultState.Error(-1, e.message ?: "未知错误"))
                }.collect {result ->
                    dismissLoading()
                    when(result) {
                        is ResultState.Success -> {
                            Log.e("数据", "${result.data}")
                            onSuccess(result.data)
                        }
                        is ResultState.Error -> {
                            onError?.invoke(result.code, result.message) ?:
                            showError("错误码: ${result.code}, 错误信息: ${result.message}")
                        }
                        is ResultState.Exception -> {
                            onException?.invoke(result.throwable) ?: showError(result.throwable.message ?: "未知错误")
                        }
                        is ResultState.Toast -> {
                            onToast(result.message)
                        }
                        else -> {

                        }

                    }
                }

            }

    }


    // 处理网络请求的通用方法
    protected fun <T> handlePagingRequest(
        showLoading: Boolean = true,
        loading: String = "加载中...",
        flow: Flow<ResultState<PageData<T>>>,
        onSuccess:  (List<T>) -> Unit,
        onError: ((Int, String) -> Unit)? = null,
        onException: ((Throwable) -> Unit)? = null,
    ) {
        viewModelScope.launch {
            flow.onStart {
                if (showLoading) showLoading(loading)
            }.catch { e ->
                dismissLoading()
                onException?.invoke(e) ?:
                _refreshLoadStatus.emit(RefreshLoadStatus.Error(e))
                emit(ResultState.Error(-1, e.message ?: "未知错误"))
            }.collect {result ->
                dismissLoading()
                when(result) {

                    is ResultState.Success -> {
                        _refreshLoadStatus.emit(RefreshLoadStatus.Success(result.data.total))
                        onSuccess(result.data.records)
                    }
                    is ResultState.Error -> {
                        onError?.invoke(result.code, result.message) ?:
                        showError("错误码: ${result.code}, 错误信息: ${result.message}")
                    }
                    is ResultState.Exception -> {
                        onException?.invoke(result.throwable) ?: showError(result.throwable.message ?: "未知错误")
                    }else -> {}

                }
            }

        }

    }
}




/**
 * UI 状态
 */
sealed class UiState {
    object Idle : UiState()
    data class ShowLoading(val loading: String) : UiState()
    object DismissLoading : UiState()
    data class Error(val message: String) : UiState()
}

/**
 * 刷新 状态
 */
sealed class RefreshLoadStatus {
    data class Success(val total: Int) : RefreshLoadStatus()
    data class Error(val throwable: Throwable) : RefreshLoadStatus()
}